﻿using System;

using NetNames.Objects;

namespace NetNames.Sample {

    internal class MyClass {

        // NetNames is able to get the names of public fields.
        public bool MyField = default(bool);

        // NetNames can also do properties. Only a public getter
        // is necessary. The setter can be private.
        public string MyProperty { get; private set; }

        // Methods that return something are no problem. Notice
        // that this method throws an exception. The method is
        // never actually called during name resolution, so this
        // exception will never be thrown.
        public object MyFunc() {
            throw new NotSupportedException();
        }

        // NetNames can also get the names of methods that don't
        // return anything. Methods can also take parameters. The
        // parameter values are not important and are not used
        // during name resolution.
        public void MyAction(int param) { }
    }

    internal class Program {
        static void Main(string[] args) {

            // The NetNames namespace contains static
            // methods for resolving the names of type
            // members.
            Console.WriteLine("The following member names are gotten from a static method.");
            Console.WriteLine("Name of 'MyField' field: " + MemberName<MyClass>.Of(c => c.MyField));
            Console.WriteLine("Name of 'MyProperty' property: " + MemberName<MyClass>.Of(c => c.MyProperty));
            Console.WriteLine("Name of 'MyFunc' method: " + MemberName<MyClass>.Of(c => c.MyFunc()));
            Console.WriteLine("Name of 'MyAction' method: " + MemberName<MyClass>.Of(c => c.MyAction(0)));

            // The NetNames.Objects namespace contains
            // extension methods that can be used on
            // any object
            var obj = new MyClass();
            Console.WriteLine();
            Console.WriteLine("The following member names are gotten from an instance.");
            Console.WriteLine("Name of 'MyField' instance field: " + obj.GetMemberName(o => o.MyField));
            Console.WriteLine("Name of 'MyProperty' instance property: " + obj.GetMemberName(o => o.MyProperty));
            Console.WriteLine("Name of 'MyFunc' instance method: " + obj.GetMemberName(o => o.MyFunc()));
            Console.WriteLine("Name of 'MyAction' instance method: " + obj.GetMemberName(o => o.MyAction(0)));

            // What's the point?
            // How about a strongly-typed method of getting MethodInfo?
            var myFuncInfo = typeof(MyClass).GetMethod(MemberName<MyClass>.Of(c => c.MyFunc()));
            Console.WriteLine();
            Console.WriteLine("'MyFunc' name from MethodInfo: " + myFuncInfo.Name);

            Console.WriteLine();
            Console.WriteLine("Press any key to exit.");
            Console.ReadKey();
        }
    }
}
